﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Windows.Forms;

namespace DACK_MHTTUD_0912008_0912493
{
    public class DES_Algorithm
    {
        private PaddingMode Padding_Mode { get; set; }
        private CipherMode Mode_Of_Operation { get; set; }
        private byte[] Key_Array { get; set; }
        private byte[] IV_Array { get; set; }
        public DES_Algorithm(string str_padding, string str_mode, string str_key, string str_iv)
        {
            PaddingMode paddingmode = DES_Padding.Get_Padding_Mode_From_String(str_padding);
            CipherMode modeofoperation = DES_Mode.Get_Cipher_Mode_From_String(str_mode);
            byte[] key_array = ASCIIEncoding.ASCII.GetBytes(str_key);
            byte[] iv_array = ASCIIEncoding.ASCII.GetBytes(str_iv);
            Padding_Mode = paddingmode;
            Mode_Of_Operation = modeofoperation;
            Key_Array = key_array;
            IV_Array = iv_array;
        }

        public bool DES_Encrypt(string path_file_in, string path_folder_out)
        {
            CryptoStream encStream = null;
            FileStream file_stream_in = null, file_stream_out = null;
            try
            {
                //Create the file streams to handle the input and output files.
                file_stream_in = new FileStream(path_file_in, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                path_folder_out += "\\" + Path.GetFileName(path_file_in) + ".DES";
                file_stream_out = new FileStream(path_folder_out, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                file_stream_out.SetLength(0);

                //Create variables to help with read and write. 
                byte[] bin = new byte[100]; //This is intermediate storage for the encryption. 
                long rdlen = 0;              //This is the total number of bytes written. 
                long totlen = file_stream_in.Length;    //This is the total length of the input file. 
                int len;                     //This is the number of bytes to be written at a time.

                DES des = new DESCryptoServiceProvider();
                des.Padding = Padding_Mode;
                des.Mode = Mode_Of_Operation;
                encStream = new CryptoStream(file_stream_out, des.CreateEncryptor(Key_Array, IV_Array), CryptoStreamMode.Write);
                //Read from the input file, then encrypt and write to the output file. 
                while (rdlen < totlen)
                {
                    len = file_stream_in.Read(bin, 0, 100);
                    encStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                    //Console.WriteLine("{0} bytes processed", rdlen);
                }

                encStream.Close();
                file_stream_out.Close();
                file_stream_in.Close();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            return true;
        }

        public bool DES_Decrypt(string path_file_in, string path_folder_out)
        {
            CryptoStream encStream = null;
            FileStream file_stream_in = null, file_stream_out = null;
            try
            {
                //Create the file streams to handle the input and output files.
                file_stream_in = new FileStream(path_file_in, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                path_folder_out += "\\" + Path.GetFileName(path_file_in);
                path_folder_out = path_folder_out.Replace(".DES", "");
                file_stream_out = new FileStream(path_folder_out, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                file_stream_out.SetLength(0);

                //Create variables to help with read and write. 
                byte[] bin = new byte[100]; //This is intermediate storage for the encryption. 
                long rdlen = 0;              //This is the total number of bytes written. 
                long totlen = file_stream_in.Length;    //This is the total length of the input file. 
                int len;                     //This is the number of bytes to be written at a time.

                DES des = new DESCryptoServiceProvider();
                des.Padding = Padding_Mode;
                des.Mode = Mode_Of_Operation;
                encStream = new CryptoStream(file_stream_out, des.CreateDecryptor(Key_Array, IV_Array), CryptoStreamMode.Write);
                //Read from the input file, then encrypt and write to the output file. 
                while (rdlen < totlen)
                {
                    len = file_stream_in.Read(bin, 0, 100);
                    encStream.Write(bin, 0, len);
                    rdlen = rdlen + len;
                }
                encStream.Close();
                file_stream_in.Close();
                file_stream_out.Close();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            return true;
        }
    }
}
